package com.ndp.fb.walle.business.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.ndp.fb.enums.account.AccountOperateType;
import com.ndp.fb.mq.api.producer.AssetsAlertProducerService;
import com.ndp.fb.mq.api.service.schedulerservice.business.syncbusiness.SyncAccountResourceService;
import com.ndp.fb.rdb.api.AccountOperateHistoryRdbService;
import com.ndp.fb.rdb.api.EntrustAccountRdbService;
import com.ndp.fb.rdb.api.FbUserPermissionRdbService;
import com.ndp.fb.rdb.api.FbUserRdbService;
import com.ndp.fb.rdb.model.*;
import com.ndp.fb.util.DateUtil;
import com.ndp.fb.walle.business.EntrustAccountService;
import com.ndp.fb.walle.model.bo.entrustaccount.AccountOperateHistoryResult;
import com.ndp.fb.walle.util.ResponseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * Created by infi on 2015/1/30.
 */
@Component
class EntrustAccountServiceImpl implements EntrustAccountService {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Reference
    private EntrustAccountRdbService entrustAccountRdbService;

    @Reference
    private FbUserPermissionRdbService fbUserPermissionRdbService;

    @Reference
    private FbUserRdbService fbUserRdbService;

    @Reference
    private AccountOperateHistoryRdbService accountOperateHistoryRdbService;

    @Reference
    private SyncAccountResourceService syncAccountResourceService;

    @Autowired
    private AssetsAlertProducerService assetsAlertProducerService;


    @Override
    public List<EntrustAccountExt> findEntrustAccountsByfbConnectionObjectIdAndUserId(Long fbConnectionObjectId, String userId) {
        return entrustAccountRdbService.findByConnectionObjectIdAndUserId(fbConnectionObjectId, userId);
    }

    @Override
    public boolean saveOrUpdateEntrust(List<EntrustAccount> recycleEntrustAccounts, List<EntrustAccount> allEntrustAccounts, String userId, List<Long> ids) {

        //回收的账号不做任何操作，数据库继续保留

        //保存新增的账号
        for (EntrustAccount entrustAccount : allEntrustAccounts) {

            entrustAccount.setIsUpdatedResource(0);
            entrustAccountRdbService.saveorupdateAdaccount(entrustAccount);
            assetsAlertProducerService.notificationAccountAlert(userId,entrustAccount.getFbAccountId(),AccountOperateType.ADD);

        }

        if (!CollectionUtils.isEmpty(allEntrustAccounts)) {

            //需要更新的操作记录
            List<EntrustAccount> needUpdateEntrustAccounts = new ArrayList<EntrustAccount>();
            List<EntrustAccount> needAddEntrustAccounts = new ArrayList<EntrustAccount>();

            //过滤账号增加和更新
            for(EntrustAccount entrustAccount:allEntrustAccounts){
                if( !ids.contains(entrustAccount.getFbAccountId() )){
                    needUpdateEntrustAccounts.add(entrustAccount);
                }else{
                	needAddEntrustAccounts.add(entrustAccount);
                }
            }

            if(!CollectionUtils.isEmpty(needAddEntrustAccounts)){
            	 //账号增加操作记录
                AccountOperateHistory accountOperateHistoryAdd = new AccountOperateHistory();
                accountOperateHistoryAdd.setDate(System.currentTimeMillis());
                accountOperateHistoryAdd.setAccountOperateType(AccountOperateType.ADD);
                accountOperateHistoryAdd.setAccounts(entrustAccountListToNameString(needAddEntrustAccounts,ids,true));
                accountOperateHistoryAdd.setUserId(userId);
                accountOperateHistoryRdbService.save(accountOperateHistoryAdd);
            }

            if(!CollectionUtils.isEmpty(needUpdateEntrustAccounts)){
                //账号更新操作记录
                AccountOperateHistory accountOperateHistoryUpdate = new AccountOperateHistory();
                accountOperateHistoryUpdate.setDate(System.currentTimeMillis());
                accountOperateHistoryUpdate.setAccounts(entrustAccountListToNameString(needUpdateEntrustAccounts,ids,false));
                accountOperateHistoryUpdate.setUserId(userId);
                accountOperateHistoryUpdate.setAccountOperateType(AccountOperateType.UPDATE);
                accountOperateHistoryRdbService.save(accountOperateHistoryUpdate);
            }
        }

        if (recycleEntrustAccounts != null && recycleEntrustAccounts.size() > 0) {

            for (EntrustAccount entrustAccount : recycleEntrustAccounts) {
                entrustAccount.setIsUpdatedResource(0);
                entrustAccountRdbService.saveorupdateAdaccount(entrustAccount);
                syncAccountResourceService.syncCustomaudiences(entrustAccount.getFbAccountId(),userId);
            }

        }
        return true;
    }

    /**
     * 账户List转Name
     * @param entrustAccountList
     * @return
     */
    private String entrustAccountListToNameString(List<EntrustAccount> entrustAccountList,List<Long> ids,boolean flag) {
        StringBuffer sb = new StringBuffer();
        int i = 0;
        for (EntrustAccount entrustAccount : entrustAccountList) {
            if(flag){
                if(ids.contains(entrustAccount.getFbAccountId())){
                    i = getEntrustAccount(entrustAccountList, sb, i, entrustAccount);
                }
            }else{
                i = getEntrustAccount(entrustAccountList, sb, i, entrustAccount);
            }

        }
        return sb.toString();
    }

    private int getEntrustAccount(List<EntrustAccount> entrustAccountList, StringBuffer sb, int i, EntrustAccount entrustAccount) {
        if (entrustAccount.getName() != null && !entrustAccount.getName().equals("")) {
            sb.append(entrustAccount.getName());
        } else {
            sb.append(entrustAccount.getFbAccountId());
        }
        if (i++ < entrustAccountList.size() - 1) {
            sb.append(",");
        }
        return i;
    }

    /**
     * @param accountId
     * @return
     * @discription
     * @author giser.yang
     * 创建时间 2015年6月3日 下午2:25:03
     * @see com.ndp.fb.walle.business.EntrustAccountService#getTokenByFbAccountId(java.lang.Long)
     */

    @Override
    public String getTokenByFbAccountId(Long accountId) {
        List<AdAccountPermission> userPermissions = fbUserPermissionRdbService.getUserpermissions(accountId);
        if (CollectionUtils.isEmpty(userPermissions)) {
            logger.error("账号:" + accountId + "没有用户使用它");
            return null;
        }
        Long fbUserId = userPermissions.get(0).getFbUserId();
        FbUser fbUser = fbUserRdbService.getFbUserByFbUserId(fbUserId);
        if (fbUser != null) {
            return fbUser.getAccessToken();
        }
        return null;
    }

    /**
     * @param userId
     * @param offset
     * @param limit
     * @return
     * @discription
     * @author giser.yang
     * 创建时间 2015年6月3日 下午5:44:36
     */
    @Override
    public Pager<EntrustAccountExt> findEntrustAccountsPagerByUserId(
            String userId, Long businessId, Integer offset, Integer limit) {
        // TODO Auto-generated method stub
        return entrustAccountRdbService.findEntrustAccountsPagerByUserId(userId, businessId, offset, limit);
    }

    /**
     * @param userId
     * @return
     * @discription
     * @author giser.yang
     * 创建时间 2015年6月5日 下午12:13:09
     * @see com.ndp.fb.walle.business.EntrustAccountService#findEntrustAccountsByUserId(java.lang.String)
     */

    @Override
    public List<EntrustAccountExt> findEntrustAccountsByUserId(String userId) {
        return entrustAccountRdbService.findAdAccountListByUserIdAll(userId);
    }


    @Override
    public Boolean unBindEntrustAccount(Long fb_account_id, Long fb_business_id, User user) {

        FbUser fbUser = fbUserRdbService.getFbUserByUserId(user.getTicket());
        if (fbUser != null) {
            AdAccountPermission userpermission = fbUserPermissionRdbService.getUserpermission(fb_account_id, fbUser.getFbUserId(), fb_business_id);
            if (userpermission != null) {
                try {
                    EntrustAccount entrustAccount = entrustAccountRdbService.findbyEntrustAccountId(userpermission.getFbAccountId(), 0);
                    if( entrustAccount !=null ){
                        entrustAccount.setIsUpdatedResource(0);
                        entrustAccountRdbService.updateAdAccount(entrustAccount);
                        userpermission.setStatus("DISABLE");
                        fbUserPermissionRdbService.saveorupdateUserPermission(userpermission);
                        assetsAlertProducerService.notificationAccountAlert(fbUser.getUserId(),userpermission.getFbAccountId(),AccountOperateType.UPDATE);

                        AccountOperateHistory accountOperateHistory = new AccountOperateHistory();
                        accountOperateHistory.setUserId(user.getTicket());
                        accountOperateHistory.setAccountOperateType(AccountOperateType.UNBIND);
                        if ( entrustAccount.getName() != null && !entrustAccount.getName().equals("")) {
                            accountOperateHistory.setAccounts(entrustAccount.getName());
                        } else {
                            accountOperateHistory.setAccounts(fb_account_id.toString());
                        }
                        accountOperateHistory.setDate(System.currentTimeMillis());
                        accountOperateHistoryRdbService.save(accountOperateHistory);
                        return true;
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                    return false;
                }
            }
            return false;
        }
        return true;
    }

    @Override
    public List<EntrustAccountExt> findEntrustAccountsByUserIdAndConnObjId(String ticket, Long connObjId) {
        return entrustAccountRdbService.findAdAccountListByUserIdAndConnObjId(ticket, connObjId);
    }

    @Override
    public List<AccountOperateHistoryResult> getAccountOperateHistoryList(User user) {
        List<AccountOperateHistory> accountOperateHistoryList = accountOperateHistoryRdbService.findByUserId(user.getTicket());
        List<AccountOperateHistoryResult> accountOperateHistoryResults = new ArrayList<AccountOperateHistoryResult>();
        for (AccountOperateHistory accountOperateHistory : accountOperateHistoryList) {
            AccountOperateHistoryResult accountOperateHistoryResult = new AccountOperateHistoryResult();
            accountOperateHistoryResult.setId(accountOperateHistory.getId());
            accountOperateHistoryResult.setAccounts(accountOperateHistory.getAccounts());
            accountOperateHistoryResult.setDate(DateUtil.formatDate(new Date(accountOperateHistory.getDate()), "yyyy-MM-dd HH:mm:ss", TimeZone.getTimeZone(user.getTimezoneId())));
            switch (accountOperateHistory.getAccountOperateType()) {
                case ADD:
                    accountOperateHistoryResult.setOperatorType(ResponseUtils.getMsgByKey("WALLE_ADD_ACCOUNT"));
                    break;
                case UPDATE:
                    accountOperateHistoryResult.setOperatorType(ResponseUtils.getMsgByKey("WALLE_UPDATE_ACCOUNT"));
                    break;
                case DELETE:
                    accountOperateHistoryResult.setOperatorType(ResponseUtils.getMsgByKey("WALLE_DELETE_ACCOUNT"));
                    break;
                case UNBIND:
                    accountOperateHistoryResult.setOperatorType(ResponseUtils.getMsgByKey("WALLE_CANCEL_BINDING_ACCOUNT"));
                    break;
                default:
                    accountOperateHistoryResult.setOperatorType("");

            }
            accountOperateHistoryResults.add(accountOperateHistoryResult);
        }
        return accountOperateHistoryResults;
    }

    /**
     * @param userId
     * @param businessId
     * @return
     * @discription
     * @author giser.yang
     * 创建时间 2015年6月11日 下午5:11:13
     * @see com.ndp.fb.walle.business.EntrustAccountService#findEntrustAccountsByUserId(java.lang.String, java.lang.Long)
     */

    @Override
    public List<EntrustAccountExt> findEntrustAccountsByUserId(String userId,
                                                               Long businessId) {
        return entrustAccountRdbService.findAdAccountListByUserIdAndBusinessIdAll(userId, businessId);
    }
}
